/**
 * 数据库服务
 * 负责SQLite数据库的创建、连接和基本操作
 */
import { ref } from 'vue'

// 数据库名称
const DB_NAME = 'personal_assistant'
// 数据库路径
const DB_PATH = '_doc/personal_assistant.db'



// 表名常量
export const TABLES = {
  TASKS: 'tasks',
  FINANCE_RECORDS: 'finance_records',
  POMODORO_RECORDS: 'pomodoro_records',
  NOTES: 'notes',
  SETTINGS: 'settings',
  CATEGORIES: 'categories',
}

// 数据库初始化状态
// 创建一个响应式引用，初始值为false，用于跟踪数据库是否已初始化
// 当值发生变化时，依赖此值的组件会自动更新
const isInitialized = ref(false)
// 数据库是否打开
const isOpen = ref(false)
// 初始化锁，防止多次初始化
let initializing = false
// 初始化Promise
let initPromise: Promise<boolean> | null = null

/**
 * 分类接口
 */
export interface Category {
  id: string
  name: string
  type: string
  icon: string | null
  color: string
  sort: number
  isDefault: number
  isSystem: number
  createdAt: string
  updatedAt: string
}

/**
 * 数据库服务类
 */
class DatabaseService {
  // 数据库对象
  private _db: any = null

  // 添加一个全局静态变量，用于标记是否已经完成初始化
  private static hasInitialized = false;

  /**
   * 初始化数据库
   * @returns 是否初始化成功
   */
  async init(): Promise<boolean> {
    // 如果已经初始化，直接返回成功
    if (DatabaseService.hasInitialized || isInitialized.value) {
      console.log('数据库已经初始化过，跳过重复初始化')
      return true
    }

    // 如果正在初始化中，返回初始化Promise
    if (initializing && initPromise) {
      console.log('数据库正在初始化中，等待初始化完成')
      return initPromise
    }

    console.log('开始数据库初始化流程')
    initializing = true
    initPromise = new Promise<boolean>(async (resolve) => {
      try {
        // 再次检查，防止并发初始化
        if (DatabaseService.hasInitialized || isInitialized.value) {
          console.log('数据库初始化检查 - 已经完成初始化，跳过')
          resolve(true)
          return
        }
        
        console.log('开始初始化数据库...')
        
        // 确保plus环境可用
        if (typeof plus === 'undefined') {
          console.error('plus对象不可用，无法使用SQLite')
          resolve(false)
          return
        }

        // 打开数据库
        const success = await this.openDatabase()
        if (!success) {
          throw new Error('打开数据库失败')
        }

        // 创建表
        await this.createTables()
        
        // 创建索引
        await this.createIndices()
        
        // 初始化默认分类
        await this.initDefaultCategories()
        
        // 标记为已初始化
        isInitialized.value = true
        DatabaseService.hasInitialized = true; // 设置静态标记
        console.log('数据库初始化成功')
        resolve(true)
      } catch (error) {
        console.error('初始化数据库出错:', error)
        resolve(false)
      } finally {
        initializing = false
        initPromise = null
      }
    })

    return initPromise
  }

   /**
   * 检查数据库是否已初始化
   * @returns 数据库是否已初始化
   */
   async isInitialized(): Promise<boolean> {
    // 检查静态标记和响应式状态
    if (!DatabaseService.hasInitialized && !isInitialized.value) {
      return false;
    }
    
    // 额外检查数据库连接是否有效
    try {
      const isOpen = await this.ensureDatabaseOpen();
      if (!isOpen) {
        console.warn('数据库标记为已初始化，但连接测试失败');
        return false;
      }
      
      // 尝试执行一个简单查询测试数据库是否可用
      const testResult = await this.query('sqlite_master', ['count(*) as count'], `type='table'`);
      if (!testResult || testResult.length === 0) {
        console.warn('数据库查询测试失败');
        return false;
      }
      
      return true;
    } catch (error) {
      console.error('检查数据库初始化状态出错:', error);
      return false;
    }
  }
  
  /**
   * 检查数据库是否已初始化（同步版本，仅检查状态标记）
   * @returns 数据库是否已初始化（根据状态标记）
   */
  isInitializedSync(): boolean {
    return DatabaseService.hasInitialized || isInitialized.value;
  }

  /**
   * 打开数据库
   * @returns 是否成功打开
   */
  private async openDatabase(): Promise<boolean> {
    return new Promise<boolean>((resolve) => {
      try {
        // 已打开则先关闭
        // 这里判断数据库是否已打开并先关闭的原因是：
        // 1. 避免重复打开同一个数据库连接导致资源泄漏
        // 2. 确保每次获取的是新的、干净的数据库连接
        // 3. 防止因数据库连接状态不一致导致的操作错误
        // 4. 重置连接可以解决一些潜在的连接问题
        if (this._db) {
          this._db.close()
          this._db = null
          isOpen.value = false
        }

        // 打开数据库
        plus.sqlite.openDatabase({
          name: DB_NAME,
          path: DB_PATH,
          success: (e) => {
            console.log('打开数据库成功:', e)
            this._db = e.target
            isOpen.value = true
            
            // 尝试执行一个简单查询来验证连接是否真的有效
            plus.sqlite.selectSql({
              name: DB_NAME,
              sql: "SELECT 1",
              success: () => {
                console.log('数据库连接验证成功')
                resolve(true)
              },
              fail: (e) => {
                console.error('数据库连接验证失败:', e)
                isOpen.value = false
                this._db = null
                resolve(false)
              }
            })
          },
          fail: (e) => {
            console.error('打开数据库失败:', e)
            isOpen.value = false
            this._db = null
            resolve(false)
          }
        })
      } catch (error) {
        console.error('打开数据库过程出错:', error)
        isOpen.value = false
        this._db = null
        resolve(false)
      }
    })
  }

  /**
   * 检查数据库是否已打开，如果未打开则尝试重新打开
   * @returns 是否打开成功
   */
  private async ensureDatabaseOpen(): Promise<boolean> {
    // 如果数据库已打开，直接返回成功
    if (this._db && isOpen.value) {
      return true
    }
    
    // 尝试执行简单查询验证连接
    try {
      if (typeof plus !== 'undefined') {
        const isDbOpen = await new Promise<boolean>((resolve) => {
          plus.sqlite.selectSql({
            name: DB_NAME,
            sql: "SELECT 1",
            success: () => {
              console.log('数据库连接有效')
              resolve(true)
            },
            fail: () => {
              console.log('数据库连接无效，需要重新打开')
              resolve(false)
            }
          })
        })
        
        if (isDbOpen) {
          console.log('数据库已处于打开状态')
          isOpen.value = true
          return true
        } else {
          console.log('数据库未打开，尝试重新打开')
          return await this.openDatabase()
        }
      }
    } catch (error) {
      console.error('检查数据库状态出错:', error)
    }
    
    // 无法验证或验证失败，尝试重新打开
    return await this.openDatabase()
  }

  /**
   * 关闭数据库
   * @returns 是否成功关闭
   */
  async closeDatabase(): Promise<boolean> {
    return new Promise<boolean>((resolve) => {
      try {
        if (!this._db || !isOpen.value) {
          resolve(true)
          return
        }

        plus.sqlite.closeDatabase({
          name: DB_NAME,
          success: () => {
            console.log('关闭数据库成功')
            this._db = null
            isOpen.value = false
            resolve(true)
          },
          fail: (e) => {
            console.error('关闭数据库失败:', e)
            resolve(false)
          }
        })
      } catch (error) {
        console.error('关闭数据库过程出错:', error)
        resolve(false)
      }
    })
  }

  /**
   * 创建所有表
   */
  private async createTables(): Promise<void> {
    try {
      // 创建分类表
      await this.executeSql(`
        CREATE TABLE IF NOT EXISTS ${TABLES.CATEGORIES} (
          id TEXT PRIMARY KEY,
          name TEXT NOT NULL,
          type TEXT NOT NULL, 
          icon TEXT,
          color TEXT,
          sort INTEGER NOT NULL DEFAULT 0,
          isDefault INTEGER NOT NULL DEFAULT 0,
          isSystem INTEGER NOT NULL DEFAULT 0,
          createdAt TEXT NOT NULL,
          updatedAt TEXT NOT NULL 
        )
      `)

      // 创建任务表
      await this.executeSql(`
        CREATE TABLE IF NOT EXISTS ${TABLES.TASKS} (
          id TEXT PRIMARY KEY,
          title TEXT NOT NULL,
          categoryId TEXT,
          priority TEXT NOT NULL DEFAULT 'medium',
          date TEXT,
          timeRange TEXT,
          completed INTEGER NOT NULL DEFAULT 0,
          reminder INTEGER NOT NULL DEFAULT 0,
          description TEXT,
          attachments TEXT,
          createdAt TEXT NOT NULL,
          updatedAt TEXT NOT NULL,
          FOREIGN KEY (categoryId) REFERENCES ${TABLES.CATEGORIES}(id)
        )
      `)

      // 创建财务记录表
      await this.executeSql(`
        CREATE TABLE IF NOT EXISTS ${TABLES.FINANCE_RECORDS} (
          id TEXT PRIMARY KEY,
          amount REAL NOT NULL,
          type TEXT NOT NULL,
          categoryId TEXT,
          description TEXT,
          date TEXT NOT NULL,
          imageUrl TEXT,
          createdAt TEXT NOT NULL,
          updatedAt TEXT NOT NULL,
          FOREIGN KEY (categoryId) REFERENCES ${TABLES.CATEGORIES}(id)
        )
      `)

      // 创建番茄钟记录表
      await this.executeSql(`
        CREATE TABLE IF NOT EXISTS ${TABLES.POMODORO_RECORDS} (
          id TEXT PRIMARY KEY,
          taskId TEXT,
          startTime TEXT NOT NULL,
          endTime TEXT NOT NULL,
          duration INTEGER NOT NULL,
          completed INTEGER NOT NULL DEFAULT 1,
          notes TEXT,
          createdAt TEXT NOT NULL
        )
      `)

      // 创建笔记表
      await this.executeSql(`
        CREATE TABLE IF NOT EXISTS ${TABLES.NOTES} (
          id TEXT PRIMARY KEY,
          title TEXT NOT NULL,
          content TEXT,
          tags TEXT,
          createdAt TEXT NOT NULL,
          updatedAt TEXT NOT NULL
        )
      `)

      // 创建设置表
      await this.executeSql(`
        CREATE TABLE IF NOT EXISTS ${TABLES.SETTINGS} (
          key TEXT PRIMARY KEY,
          value TEXT NOT NULL,
          updatedAt TEXT NOT NULL
        )
      `)
      
      // 创建索引
      await this.createIndices()

      // 初始化默认分类数据
      await this.initDefaultCategories()

      console.log('所有表创建成功')
    } catch (error) {
      console.error('创建表失败:', error)
      throw error
    }
  }

  /**
   * 创建索引
   */
  private async createIndices(): Promise<void> {
    try {
      // 分类表索引
      await this.executeSql(`CREATE INDEX IF NOT EXISTS idx_categories_type ON ${TABLES.CATEGORIES} (type)`)
      await this.executeSql(`CREATE INDEX IF NOT EXISTS idx_categories_sort ON ${TABLES.CATEGORIES} (sort)`)
      await this.executeSql(`CREATE INDEX IF NOT EXISTS idx_categories_isSystem ON ${TABLES.CATEGORIES} (isSystem)`)
      
      // 任务表索引
      await this.executeSql(`CREATE INDEX IF NOT EXISTS idx_tasks_date ON ${TABLES.TASKS} (date)`)
      await this.executeSql(`CREATE INDEX IF NOT EXISTS idx_tasks_completed ON ${TABLES.TASKS} (completed)`)
      await this.executeSql(`CREATE INDEX IF NOT EXISTS idx_tasks_categoryId ON ${TABLES.TASKS} (categoryId)`)
      
      // 财务记录索引
      await this.executeSql(`CREATE INDEX IF NOT EXISTS idx_finance_date ON ${TABLES.FINANCE_RECORDS} (date)`)
      await this.executeSql(`CREATE INDEX IF NOT EXISTS idx_finance_type ON ${TABLES.FINANCE_RECORDS} (type)`)
      await this.executeSql(`CREATE INDEX IF NOT EXISTS idx_finance_categoryId ON ${TABLES.FINANCE_RECORDS} (categoryId)`)
      
      // 番茄钟记录索引
      await this.executeSql(`CREATE INDEX IF NOT EXISTS idx_pomodoro_taskId ON ${TABLES.POMODORO_RECORDS} (taskId)`)
      await this.executeSql(`CREATE INDEX IF NOT EXISTS idx_pomodoro_startTime ON ${TABLES.POMODORO_RECORDS} (startTime)`)

      console.log('所有索引创建成功')
    } catch (error) {
      console.error('创建索引失败:', error)
      throw error
    }
  }

  /**
   * 初始化默认分类数据
   * @returns 是否初始化成功
   */
  private async initDefaultCategories(): Promise<boolean> {
    try {
      // 检查是否已有分类数据
      const exists = await this.query<{count: number}>(
        TABLES.CATEGORIES, 
        ['COUNT(*) as count'], 
        'isSystem = 1'
      )
      
      if (exists.length > 0 && exists[0].count > 0) {
        console.log('默认分类已存在，跳过初始化')
        return true // 已有系统分类，不重复初始化
      }

      // 当前时间
      const now = new Date().toISOString()
      
      // 任务分类默认数据
      const taskCategories = [
        { id: 'task-work', name: '工作', type: 'task', icon: 'i-fa-solid:briefcase', color: '#4a6ee0', sort: 0, isDefault: 1, isSystem: 1, createdAt: now, updatedAt: now },
        { id: 'task-study', name: '学习', type: 'task', icon: 'i-fa-solid:book', color: '#60a5fa', sort: 1, isDefault: 0, isSystem: 1, createdAt: now, updatedAt: now },
        { id: 'task-life', name: '生活', type: 'task', icon: 'i-fa-solid:home', color: '#2dd4bf', sort: 2, isDefault: 0, isSystem: 1, createdAt: now, updatedAt: now }
      ]
      
      // 财务分类默认数据
      const financeCategories = [
        { id: 'finance-food', name: '餐饮', type: 'finance', icon: 'i-fa-solid:utensils', color: '#f97316', sort: 0, isDefault: 1, isSystem: 1, createdAt: now, updatedAt: now },
        { id: 'finance-transport', name: '交通', type: 'finance', icon: 'i-fa-solid:car', color: '#84cc16', sort: 1, isDefault: 0, isSystem: 1, createdAt: now, updatedAt: now },
        { id: 'finance-shopping', name: '购物', type: 'finance', icon: 'i-fa-solid:shopping-bag', color: '#ec4899', sort: 2, isDefault: 0, isSystem: 1, createdAt: now, updatedAt: now }
      ]
      
      // 开始事务
      await this.beginTransaction()
      
      // 插入所有默认分类
      let success = true
      for (const category of [...taskCategories, ...financeCategories]) {
        const result = await this.insert(TABLES.CATEGORIES, category)
        if (!result) {
          success = false
          break
        }
      }
      
      // 提交或回滚事务
      if (success) {
        await this.commitTransaction()
        console.log('默认分类初始化成功')
        return true
      } else {
        await this.rollbackTransaction()
        console.error('默认分类初始化失败')
        return false
      }
    } catch (error) {
      console.error('初始化默认分类数据出错:', error)
      await this.rollbackTransaction()
      return false
    }
  }

  /**
   * 执行SQL语句
   * @param sql SQL语句
   * @param args SQL参数
   * @returns 是否执行成功
   */
  async executeSql(sql: string, args: any[] = []): Promise<boolean> {
    return new Promise<boolean>(async (resolve) => {
      try {
        // 确保数据库已打开
        const isOpen = await this.ensureDatabaseOpen()
        if (!isOpen) {
          console.error('数据库未打开，无法执行SQL')
          resolve(false)
          return
        }

        plus.sqlite.executeSql({
          name: DB_NAME,
          sql: [sql],
          success: () => {
            resolve(true)
          },
          fail: (e) => {
            console.error(`执行SQL失败: ${sql}`, e)
            resolve(false)
          }
        })
      } catch (error) {
        console.error(`执行SQL出错: ${sql}`, error)
        resolve(false)
      }
    })
  }

  /**
   * 执行查询
   * @param tableName 表名
   * @param columns 要查询的列
   * @param whereClause where条件
   * @param orderByClause 排序条件
   * @param limit 限制条数
   * @returns 查询结果
   */
  async query<T>(
    tableName: string, 
    columns: string[] = ['*'], 
    whereClause: string = '', 
    orderByClause: string = '', 
    limit: number = 0
  ): Promise<T[]> {
    return new Promise<T[]>(async (resolve) => {
      try {
        // 确保数据库已打开
        const isOpen = await this.ensureDatabaseOpen()
        if (!isOpen) {
          console.error('数据库未打开，无法执行查询')
          resolve([])
          return
        }

        // 构建SQL语句
        let sql = `SELECT ${columns.join(', ')} FROM ${tableName}`
        if (whereClause) {
          sql += ` WHERE ${whereClause}`
        }
        if (orderByClause) {
          sql += ` ORDER BY ${orderByClause}`
        }
        if (limit > 0) {
          sql += ` LIMIT ${limit}`
        }

        // 执行查询
        plus.sqlite.selectSql({
          name: DB_NAME,
          sql: sql,
          success: (data) => {
            resolve(data as T[])
          },
          fail: (e) => {
            console.error(`查询失败: ${sql}`, e)
            resolve([])
          }
        })
      } catch (error) {
        console.error('查询出错', error)
        resolve([])
      }
    })
  }

  /**
   * 格式化SQL值
   * @param value 要格式化的值
   * @returns 格式化后可直接用于SQL的值
   */
  private formatValue(value: any): string {
    if (value === null || value === undefined) {
      return 'NULL'
    }
    
    if (typeof value === 'string') {
      // 处理字符串，需要转义单引号并用单引号包裹
      return `'${value.replace(/'/g, "''")}'`
    }
    
    if (typeof value === 'boolean') {
      return value ? '1' : '0'
    }
    
    if (typeof value === 'number') {
      return value.toString()
    }
    
    if (value instanceof Date) {
      return `'${value.toISOString()}'`
    }
    
    // 对于对象或数组，转为JSON字符串存储
    if (typeof value === 'object') {
      return `'${JSON.stringify(value).replace(/'/g, "''")}'`
    }
    
    return `'${String(value).replace(/'/g, "''")}'`
  }

  /**
   * 插入数据
   * @param tableName 表名
   * @param data 数据对象
   * @returns 插入结果
   */
  async insert(tableName: string, data: Record<string, any>): Promise<any> {
    try {
      const keys = Object.keys(data)
      // 使用格式化后的值而不是占位符
      const fields = keys.join(', ')
      const formattedValues = keys.map(key => this.formatValue(data[key]))
      const valuesClause = formattedValues.join(', ')
      
      const sql = `INSERT INTO ${tableName} (${fields}) VALUES (${valuesClause})`
      console.log('执行SQL:', sql)
      
      return await this.executeSql(sql)
    } catch (e) {
      console.error(`插入数据到 ${tableName} 失败:`, e)
      throw e
    }
  }

  /**
   * 更新数据
   * @param tableName 表名
   * @param data 要更新的数据
   * @param whereClause where条件
   * @returns 是否更新成功
   */
  async update(tableName: string, data: Record<string, any>, whereClause: string): Promise<boolean> {
    try {
      // 确保数据库已打开
      const isOpen = await this.ensureDatabaseOpen()
      if (!isOpen) {
        console.error('数据库未打开，无法更新数据')
        return false
      }

      // 构建SET子句
      const setClause = Object.keys(data)
        .map(key => `${key} = ${this.formatValue(data[key])}`)
        .join(', ')

      // 构建SQL语句
      const sql = `UPDATE ${tableName} SET ${setClause} WHERE ${whereClause}`
      console.log('执行SQL:', sql)

      // 执行更新
      return await this.executeSql(sql)
    } catch (error) {
      console.error('更新数据出错', error)
      return false
    }
  }

  /**
   * 删除数据
   * @param tableName 表名
   * @param whereClause where条件
   * @returns 是否删除成功
   */
  async delete(tableName: string, whereClause: string): Promise<boolean> {
    try {
      // 确保数据库已打开
      const isOpen = await this.ensureDatabaseOpen()
      if (!isOpen) {
        console.error('数据库未打开，无法删除数据')
        return false
      }

      // 构建SQL语句
      const sql = `DELETE FROM ${tableName} WHERE ${whereClause}`
      console.log('执行SQL:', sql)

      // 执行删除
      return await this.executeSql(sql)
    } catch (error) {
      console.error('删除数据出错', error)
      return false
    }
  }

  /**
   * 删除表
   * @param tableName 表名
   * @returns 是否删除成功
   */
  async dropTable(tableName: string): Promise<boolean> {
    try {
      // 确保数据库已打开
      const isOpen = await this.ensureDatabaseOpen()
      if (!isOpen) {
        console.error('数据库未打开，无法删除表')
        return false
      }

      // 构建SQL语句
      const sql = `DROP TABLE IF EXISTS ${tableName}`

      // 执行删除表
      return await this.executeSql(sql)
    } catch (error) {
      console.error('删除表出错', error)
      return false
    }
  }

  /**
   * 清空表
   * @param tableName 表名
   * @returns 是否清空成功
   */
  async clearTable(tableName: string): Promise<boolean> {
    try {
      // 确保数据库已打开
      const isOpen = await this.ensureDatabaseOpen()
      if (!isOpen) {
        console.error('数据库未打开，无法清空表')
        return false
      }

      // 构建SQL语句
      const sql = `DELETE FROM ${tableName}`

      // 执行清空表
      return await this.executeSql(sql)
    } catch (error) {
      console.error('清空表出错', error)
      return false
    }
  }

  /**
   * 检查表是否存在
   * @param tableName 表名
   * @returns 表是否存在
   */
  async tableExists(tableName: string): Promise<boolean> {
    try {
      // 确保数据库已打开
      const isOpen = await this.ensureDatabaseOpen()
      if (!isOpen) {
        console.error('数据库未打开，无法检查表是否存在')
        return false
      }

      // 查询sqlite_master表
      const result = await this.query<{ name: string }>(
        'sqlite_master',
        ['name'],
        `type = 'table' AND name = '${tableName}'`
      )

      return result.length > 0
    } catch (error) {
      console.error('检查表是否存在出错', error)
      return false
    }
  }

  /**
   * 获取表结构
   * @param tableName 表名
   * @returns 表结构信息
   */
  async getTableInfo(tableName: string): Promise<any[]> {
    try {
      // 确保数据库已打开
      const isOpen = await this.ensureDatabaseOpen()
      if (!isOpen) {
        console.error('数据库未打开，无法获取表结构')
        return []
      }

      // 查询表结构
      return await this.query<any>('pragma_table_info', ['*'], `table_name = '${tableName}'`)
    } catch (error) {
      console.error('获取表结构出错', error)
      return []
    }
  }

  /**
   * 开始事务
   * @returns 是否成功开始事务
   */
  async beginTransaction(): Promise<boolean> {
    // 确保数据库已打开
    const isOpen = await this.ensureDatabaseOpen()
    if (!isOpen) {
      console.error('数据库未打开，无法开始事务')
      return false
    }
    
    return await this.executeSql('BEGIN TRANSACTION')
  }

  /**
   * 提交事务
   * @returns 是否成功提交事务
   */
  async commitTransaction(): Promise<boolean> {
    // 确保数据库已打开
    const isOpen = await this.ensureDatabaseOpen()
    if (!isOpen) {
      console.error('数据库未打开，无法提交事务')
      return false
    }
    
    return await this.executeSql('COMMIT')
  }

  /**
   * 回滚事务
   * @returns 是否成功回滚事务
   */
  async rollbackTransaction(): Promise<boolean> {
    // 确保数据库已打开
    const isOpen = await this.ensureDatabaseOpen()
    if (!isOpen) {
      console.error('数据库未打开，无法回滚事务')
      return false
    }
    
    return await this.executeSql('ROLLBACK')
  }

  /**
   * 获取指定类型的所有分类
   * @param type 分类类型，如'task'或'finance'
   * @returns 分类列表
   */
  async getCategories(type: string): Promise<Category[]> {
    try {
      // 确保数据库已打开
      const isOpen = await this.ensureDatabaseOpen()
      if (!isOpen) {
        console.error('数据库未打开，无法获取分类')
        return []
      }

      // 查询指定类型的分类，按排序字段排序
      return await this.query<Category>(
        TABLES.CATEGORIES,
        ['*'],
        `type = ${this.formatValue(type)}`,
        'sort ASC, name ASC'
      )
    } catch (error) {
      console.error(`获取分类出错, type=${type}`, error)
      return []
    }
  }

  /**
   * 获取指定类型的默认分类
   * @param type 分类类型，如'task'或'finance'
   * @returns 默认分类，未找到则返回null
   */
  async getDefaultCategory(type: string): Promise<Category | null> {
    try {
      // 确保数据库已打开
      const isOpen = await this.ensureDatabaseOpen()
      if (!isOpen) {
        console.error('数据库未打开，无法获取默认分类')
        return null
      }

      // 查询指定类型的默认分类
      const result = await this.query<Category>(
        TABLES.CATEGORIES,
        ['*'],
        `type = ${this.formatValue(type)} AND isDefault = 1`,
        '',
        1
      )

      return result.length > 0 ? result[0] : null
    } catch (error) {
      console.error(`获取默认分类出错, type=${type}`, error)
      return null
    }
  }

  /**
   * 添加自定义分类
   * @param data 分类数据
   * @returns 是否添加成功
   */
  async addCategory(data: {
    name: string,
    type: string,
    icon?: string,
    color?: string,
    sort?: number
  }): Promise<boolean> {
    try {
      // 确保数据库已打开
      const isOpen = await this.ensureDatabaseOpen()
      if (!isOpen) {
        console.error('数据库未打开，无法添加分类')
        return false
      }

      // 生成唯一ID
      const id = `${data.type}-${Date.now()}`
      
      // 当前时间
      const now = new Date().toISOString()
      
      // 构建完整数据
      const categoryData = {
        id,
        name: data.name,
        type: data.type,
        icon: data.icon || null,
        color: data.color || '#808080',
        sort: data.sort || 100, // 自定义分类默认排在后面
        isDefault: 0,
        isSystem: 0,
        createdAt: now,
        updatedAt: now
      }
      
      // 插入数据
      return await this.insert(TABLES.CATEGORIES, categoryData)
    } catch (error) {
      console.error('添加分类出错', error)
      return false
    }
  }

  /**
   * 设置默认分类
   * @param categoryId 要设为默认的分类ID
   * @returns 是否设置成功
   */
  async setDefaultCategory(categoryId: string): Promise<boolean> {
    try {
      // 确保数据库已打开
      const isOpen = await this.ensureDatabaseOpen()
      if (!isOpen) {
        console.error('数据库未打开，无法设置默认分类')
        return false
      }
      
      // 先获取分类信息
      const categories = await this.query<Category>(
        TABLES.CATEGORIES,
        ['*'],
        `id = ${this.formatValue(categoryId)}`
      )
      
      if (categories.length === 0) {
        console.error(`分类不存在: ${categoryId}`)
        return false
      }
      
      const category = categories[0]
      
      // 开始事务
      await this.beginTransaction()
      
      // 1. 先将该类型的所有分类设为非默认
      const clearDefault = await this.update(
        TABLES.CATEGORIES,
        { isDefault: 0, updatedAt: new Date().toISOString() },
        `type = ${this.formatValue(category.type)}`
      )
      
      if (!clearDefault) {
        await this.rollbackTransaction()
        return false
      }
      
      // 2. 将指定分类设为默认
      const setDefault = await this.update(
        TABLES.CATEGORIES,
        { isDefault: 1, updatedAt: new Date().toISOString() },
        `id = ${this.formatValue(categoryId)}`
      )
      
      if (!setDefault) {
        await this.rollbackTransaction()
        return false
      }
      
      // 提交事务
      await this.commitTransaction()
      return true
    } catch (error) {
      console.error(`设置默认分类出错: ${categoryId}`, error)
      await this.rollbackTransaction()
      return false
    }
  }

  /**
   * 更新分类
   * @param categoryId 分类ID
   * @param data 要更新的数据
   * @returns 是否更新成功
   */
  async updateCategory(categoryId: string, data: {
    name?: string,
    icon?: string,
    color?: string,
    sort?: number
  }): Promise<boolean> {
    try {
      // 确保数据库已打开
      const isOpen = await this.ensureDatabaseOpen()
      if (!isOpen) {
        console.error('数据库未打开，无法更新分类')
        return false
      }
      
      // 检查分类是否存在
      const categories = await this.query<Category>(
        TABLES.CATEGORIES,
        ['isSystem'],
        `id = ${this.formatValue(categoryId)}`
      )
      
      if (categories.length === 0) {
        console.error(`分类不存在: ${categoryId}`)
        return false
      }
      
      // 不允许修改系统分类的名称
      if (categories[0].isSystem === 1 && data.name) {
        console.error('不允许修改系统分类的名称')
        return false
      }
      
      // 添加更新时间
      const updateData = {
        ...data,
        updatedAt: new Date().toISOString()
      }
      
      // 更新分类
      return await this.update(
        TABLES.CATEGORIES,
        updateData,
        `id = ${this.formatValue(categoryId)}`
      )
    } catch (error) {
      console.error(`更新分类出错: ${categoryId}`, error)
      return false
    }
  }

  /**
   * 删除分类
   * @param categoryId 分类ID
   * @returns 是否删除成功
   */
  async deleteCategory(categoryId: string): Promise<boolean> {
    try {
      // 确保数据库已打开
      const isOpen = await this.ensureDatabaseOpen()
      if (!isOpen) {
        console.error('数据库未打开，无法删除分类')
        return false
      }
      
      // 检查分类是否存在
      const categories = await this.query<Category>(
        TABLES.CATEGORIES,
        ['isSystem', 'isDefault', 'type'],
        `id = ${this.formatValue(categoryId)}`
      )
      
      if (categories.length === 0) {
        console.error(`分类不存在: ${categoryId}`)
        return false
      }
      
      const category = categories[0]
      
      // 不允许删除系统分类
      if (category.isSystem === 1) {
        console.error('不允许删除系统分类')
        return false
      }
      
      // 不允许删除默认分类
      if (category.isDefault === 1) {
        console.error('不允许删除默认分类，请先设置其他分类为默认')
        return false
      }
      
      // 开始事务
      await this.beginTransaction()
      
      // 获取该类型的默认分类
      const defaultCategories = await this.query<Category>(
        TABLES.CATEGORIES,
        ['id'],
        `type = ${this.formatValue(category.type)} AND isDefault = 1`
      )
      
      if (defaultCategories.length === 0) {
        await this.rollbackTransaction()
        console.error('找不到默认分类')
        return false
      }
      
      const defaultCategoryId = defaultCategories[0].id
      
      // 1. 将使用该分类的记录更新为使用默认分类
      if (category.type === 'task') {
        const updateTasks = await this.update(
          TABLES.TASKS,
          { categoryId: defaultCategoryId, updatedAt: new Date().toISOString() },
          `categoryId = ${this.formatValue(categoryId)}`
        )
        
        if (!updateTasks) {
          await this.rollbackTransaction()
          return false
        }
      } else if (category.type === 'finance') {
        const updateFinance = await this.update(
          TABLES.FINANCE_RECORDS,
          { categoryId: defaultCategoryId, updatedAt: new Date().toISOString() },
          `categoryId = ${this.formatValue(categoryId)}`
        )
        
        if (!updateFinance) {
          await this.rollbackTransaction()
          return false
        }
      }
      
      // 2. 删除分类
      const deleteResult = await this.delete(
        TABLES.CATEGORIES,
        `id = ${this.formatValue(categoryId)}`
      )
      
      if (!deleteResult) {
        await this.rollbackTransaction()
        return false
      }
      
      // 提交事务
      await this.commitTransaction()
      return true
    } catch (error) {
      console.error(`删除分类出错: ${categoryId}`, error)
      await this.rollbackTransaction()
      return false
    }
  }

  /**
   * 获取分类类型列表
   * @returns 所有分类类型的列表
   */
  async getCategoryTypes(): Promise<string[]> {
    try {
      // 确保数据库已打开
      const isOpen = await this.ensureDatabaseOpen()
      if (!isOpen) {
        console.error('数据库未打开，无法获取分类类型')
        return []
      }

      // 查询不同的分类类型
      const result = await this.query<{type: string}>(
        TABLES.CATEGORIES,
        ['DISTINCT type as type'],
        ''
      )
      
      return result.map(item => item.type)
    } catch (error) {
      console.error('获取分类类型出错', error)
      return []
    }
  }
}

// 创建单例
export const dbService = new DatabaseService() 